package com.example.charlotte.snakegame;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.os.Build;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;

import java.io.IOException;
import java.util.ArrayList;

class SnakeView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    private String color[] = {"#424542", "#ffffff", "#00ff00", "#0a94ff", "#cecece", "#ffff00","#8023f3","#ffdb4b"};  //黑，白，绿，蓝，灰，黄，紫，橙
    private String level[] = {"顽强黑铁", "热血青铜", "傲气白银", "荣耀黄金","尊贵铂金","永恒钻石","最强王者"};

    private final SurfaceHolder holder;
    private GestureDetector gestureDetector;
    private final float scaleX;
    private final float scaleY;
    private boolean isRun;
    private Paint paint;
    private ArrayList<Block> blocks;
    private boolean gameOver;
    private Block head;
    private Food food;
    private int score;
    private long lastMove;
    private RectF rectF;
    static int moveDelay;
    static GameMusic music;
    private int  extraScore;
    private Context context;
    private String title;

    public SnakeView(Context context) {
        super(context);
        this.context=context;
        holder = getHolder();
        holder.addCallback(this);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        music = new GameMusic(context);
        Point screenSize = new Point();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (windowManager != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                windowManager.getDefaultDisplay().getRealSize(screenSize); //包含虚拟导航键的尺寸
            } else {
                windowManager.getDefaultDisplay().getSize(screenSize);
            }
        }

        scaleX = (float) screenSize.x / 720; //计算缩放比例（768*1280是模拟器的尺寸）
        scaleY = (float) screenSize.y / 1280;
        blocks = new ArrayList<>();
        food = new Food();
        init();

        gestureDetector = new GestureDetector(context,
                new GestureDetector.SimpleOnGestureListener() {

                    @Override
                    public boolean onSingleTapUp(MotionEvent e) {
                        singleTap(e);
                        return super.onSingleTapUp(e);
                    }
                });
    }

    public void singleTap(MotionEvent e) {
        if (gameOver) {
            rectF.set(155 * scaleX, 540 * scaleY, 245 * scaleX, 620 * scaleY);
            if (rectF.contains(e.getX(), e.getY()))
            {
                music.startMusic(3);
            }
            rectF.set(315 * scaleX, 540 * scaleY, 405 * scaleX, 620 * scaleY);
            if (rectF.contains(e.getX(), e.getY()))
            {
                music.startMusic(3);
                GameActivity.instance.finish();

            }
            rectF.set(475 * scaleX, 540 * scaleY, 565 * scaleX, 620 * scaleY);
            if (rectF.contains(e.getX(), e.getY()))
            {
                music.startMusic(3);
                init();
            }

        } else {

            rectF.set(300 * scaleX, 1160 * scaleY, 420 * scaleX, 1280 * scaleY);
            if (rectF.contains(e.getX(), e.getY()))
            {
                if (head.getDir() != Block.UP) {
                    head.setDir(Block.DOWN);

                }
            }

            rectF.set(300 * scaleX, 960 * scaleY, 420 * scaleX, 1080 * scaleY);
            if (rectF.contains(e.getX(), e.getY())) {
                if (head.getDir() != Block.DOWN) {
                    head.setDir(Block.UP);
                }
            }
            rectF.set(170 * scaleX, 1060 * scaleY, 290 * scaleX, 1180 * scaleY);
            if (rectF.contains(e.getX(), e.getY())) {
                if (head.getDir() != Block.RIGHT) {
                    head.setDir(Block.LEFT);
                }

            }

            rectF.set(430 * scaleX, 1060 * scaleY, 550 * scaleX, 1180 * scaleY);
            if (rectF.contains(e.getX(), e.getY())) {
                if (head.getDir() != Block.LEFT) {
                    head.setDir(Block.RIGHT);
                }

            }
        }

    }

    private void init() {

        rectF = new RectF();
        score = 0;
        gameOver = false;
        blocks.clear();
        for (int i = 0; i < 10; i++) {  //初始化贪吃蛇10节
            blocks.add(new Block(500 + Block.WIDTH * i, 500, Block.LEFT));
        }
        head = blocks.get(0);
        setFood();
        music.startMusic(0);


    }

    private void setFood() {
        food.reset();
        for (Block block : blocks) {
            if (block.getX() == food.getX() && block.getY() == food.getY()) {
                setFood(); //判断随机设置的食物是否出现在蛇身中，是的话重新设置
                break;
            }
        }

    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        isRun = true;
        new Thread(this).start();

    }


    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        isRun = false;

    }

    @Override
    public void run() {
        while (isRun) {
            long startTime = System.currentTimeMillis();
            if (startTime - lastMove > moveDelay) {
                logic();
                redraw();
                lastMove = startTime;
            }
            try {
                Thread.sleep(moveDelay);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    private void redraw() {
        Canvas lockCanvas = holder.lockCanvas();
        try {
            synchronized (holder) {
                myDraw(lockCanvas);

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (lockCanvas != null) {
                holder.unlockCanvasAndPost(lockCanvas);
            }
        }
    }


    private Bitmap getBitmap(String path) {
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeStream(context.getAssets().open(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }


    private void myDraw(Canvas canvas) {
        canvas.save();
        canvas.scale(scaleX, scaleY);
        canvas.drawColor(Color.parseColor("#bce5b5"));
        paint.reset();

        //底部白色
        paint.setColor(Color.WHITE);
        canvas.drawRect(0, 960, 720, 1280, paint);

        // 顶部白色
        canvas.drawRect(0, 0, 720, 60, paint);

        //绘制按键
        canvas.drawBitmap(getBitmap("left_press.png"), 170, 1060, null);
        canvas.drawBitmap(getBitmap("up_press.png"), 300, 960, null);
        canvas.drawBitmap(getBitmap("down_press.png"), 300, 1160, null);
        canvas.drawBitmap(getBitmap("right_press.png"), 430, 1060, null);

        //绘制边界，上，下，左，右
        paint.setColor(Color.parseColor("#21793a"));
        canvas.drawRect(0, 60, 720, 80, paint);
        canvas.drawRect(0, 940, 720, 960, paint);
        canvas.drawRect(0, 60, 20, 960, paint);
        canvas.drawRect(700, 60, 720, 960, paint);

        food.draw(canvas, paint);
        Draw2(canvas);

        if (gameOver) {
            paint.setTextAlign(Paint.Align.CENTER);

            //绘制面板
            canvas.drawBitmap(getBitmap("panel.png"), 100, 300, null);
            canvas.drawBitmap(getBitmap("button.png"), 155, 530, null);
            paint.setTextSize(36);
            paint.setColor(Color.parseColor("#000000"));
            paint.setTextAlign(Paint.Align.CENTER);
            canvas.drawText("本局积分："+ score, 370, 500, paint);
            canvas.drawText("恭喜获得称号："+ title, 370, 450, paint);
            music.stopGameMusic();

        }
        canvas.restore();
    }
    public void drawText(Canvas canvas, Paint paint,String levelText){
        paint.setTextAlign(Paint.Align.LEFT);
        paint.setTextSize(30);
        paint.setColor(Color.BLACK);
        canvas.drawText("当前："+levelText, 20, 40, paint);
        paint.setTextAlign(Paint.Align.RIGHT);
        canvas.drawText("积分：" + score, 690, 40, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        gestureDetector.onTouchEvent(event);
        performClick();

        return true;
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }

    private void logic() {
        if (!gameOver) {
            for (Block block : blocks) {
                block.logic();
            }
            for (int i = blocks.size() - 1; i > 0; i--) {
                blocks.get(i).setDir(blocks.get(i - 1).getDir());

            }
            outBounds();
            eatFood();
            eatSelf();
        }
    }

    private void eatFood() {
        if (head.getX() == food.getX() && head.getY() == food.getY()) {  //蛇头坐标与食物的坐标重合说明吃到了食物
            Block end = blocks.get(blocks.size() - 1);
            switch (end.getDir()) {
                case Block.LEFT:           //末尾添加
                    blocks.add(new Block(end.getX() + Block.WIDTH, end.getY(), end.getDir()));
                    break;
                case Block.RIGHT:
                    blocks.add(new Block(end.getX() - Block.WIDTH, end.getY(), end.getDir()));
                    break;
                case Block.UP:
                    blocks.add(new Block(end.getX(), end.getY() + Block.WIDTH, end.getDir()));
                    break;
                case Block.DOWN:
                    blocks.add(new Block(end.getX(), end.getY() - Block.WIDTH, end.getDir()));
                    break;
            }
            setFood();
            music.startMusic(1);
            switch (moveDelay){
                case ChoiceActivity.HARD:
                    extraScore=30;
                    break;
                case ChoiceActivity.NORMAL:
                    extraScore=20;
                    break;
                case ChoiceActivity.ESEY:
                    extraScore=10;
                    break;
            }
            score+=extraScore;


        }

    }

    private void eatSelf() {
        for (int i = 4; i < blocks.size(); i++) {  //蛇头坐标与蛇身的坐标重合说明吃到了自身
            if (blocks.get(i).getX() == head.getX() && blocks.get(i).getY() == head.getY()) {
                gameOver = true;
                music.startMusic(2);
                break;
            }

        }
    }

    private void outBounds() {  //头部超出了边界，游戏结束，坐标的左上角，边界处理时需加上自身的宽度
        if (head.getX() < 20 || head.getX() + Block.WIDTH > 700 || head.getY() < 80 || head.getY() + Block.WIDTH > 940) {
            gameOver = true;
            music.startMusic(2);

        }
    }

    public void Draw2(Canvas canvas){
        for (Block block : blocks) {

        if (score >= 60) {
            title =level[6];
            block.drawBody(canvas, paint, color[5], color[6]); //王者
            drawText(canvas,paint, title);

        }else if (score >= 50) {
            title =level[5];
            block.drawBody(canvas, paint, color[1], color[3]); //钻石
            drawText(canvas,paint, title);

        }else if (score >= 40) {
            title =level[4];
            block.drawBody(canvas, paint, color[7], color[1]);  //铂金
            drawText(canvas,paint, title);

        } else if (score >= 30) {
            title =level[3];
            block.drawBody(canvas, paint, color[5], color[7]); //黄金
            drawText(canvas,paint, title);

        } else if (score >= 20) {
            title =level[2];
            block.drawBody(canvas, paint, color[1], color[4]); //白银
            drawText(canvas,paint, title);

        } else if (score >= 10) {
            title =level[1];
            block.drawBody(canvas, paint, color[0], color[2]); //青铜
            drawText(canvas,paint, title);

        } else {
            title =level[0];
            block.drawBody(canvas, paint, color[0], color[0]);  //黑铁
            drawText(canvas,paint, title);
        }
        head.drawHead(canvas, paint);
    }
    }

}
